classdef au1_params < handle
    properties
        
        % lts cells structure
        lts = struct();
        
        % ib cells structure
        ib = struct();
        
        % number of cells
        n_cells = 0;
        
        % time
        dt
        n_steps
        max_time
        time = [];
        
        % connectivity
        connect_mode
        connect = struct();
        
    end
    
    methods
        
        function p = au1_params()
            % au1_parameters - parameter class for the au1 simulation
            %
            % this function initializes all the parameters to their default
            % values, other functions can be used to set particular parameters
            % to non-default values
            
            % set default parameters
            
            % set time and steps
            p.dt = .01;
            p.n_steps = 100;
            p.setTimeBySteps(p.dt,p.n_steps);
            
            % set number of cells
            n_lts = 1;
            n_ib = 1;
            p.setNCells(n_lts,n_ib);
            
            % lts params
            
            p.lts.V_init = -60;
            p.setLtsInitV(p.lts.V_init);
            
            p.lts.n_current_param = 3;
            
            p.lts.g_NaFL = 200;
            p.lts.g_KDRL = 10;
            p.lts.g_ARL = 50;
            p.lts.g_Leak = 6;
            p.lts.g_LL = 5;
            p.lts.tau_saL_r = 2.5;
            p.lts.tau_saL_d = 50;
            p.lts.tau_sLL_r = 0.5;
            p.lts.tau_sLL_d = 20;
            p.lts.C = 1;
            p.lts.g_aL = 0.95;
            p.lts.Vk_L = 80;
            p.lts.Vk_a = 0;
            
            p.lts.J = 20;
            p.setLtsJ(p.lts.J);
            
            % IB Cell Params
            
            % initial voltage (default is same to all compartments)
            p.ib.V_init = -50;
            
            p.setIbAdInitV(p.ib.V_init);
            p.setIbAxInitV(p.ib.V_init);
            p.setIbSoInitV(p.ib.V_init);
            
            % ad
            
            p.ib.ad.n_current_param = 5; % n of updated parameters in diffeq
            
            p.ib.ad.g_NaFd = 125;
            p.ib.ad.g_KDRd = 10;
            p.ib.ad.g_ARd = 135;
            p.ib.ad.g_Leak = 2;
            p.ib.ad.g_CaHd = 6.5;
            p.ib.ad.g_KMd = 0.75;
            p.ib.ad.tau_sLd_r = 0.5;
            p.ib.ad.tau_sLd_d = 20;
            p.ib.ad.C = 1;
            
            % connectivity
            p.ib.ad.g_sd = 0.2;
            p.ib.ad.g_Ld = 2;
            p.ib.ad.g_dI = 0;
            
            p.ib.ad.Vk_L = 80;
            p.ib.ad.Vk_a = 0;
            
            p.ib.ad.J = 5;
            p.setIbAdJ(p.ib.ad.J);
            
            % ax
            
            p.ib.ax.n_current_param = 3; % n of updated parameters in diffeq
            
            p.ib.ax.g_NaFa = 100;
            p.ib.ax.g_KDRa = 5;
            p.ib.ax.g_KMa = 1.5;
            p.ib.ax.g_sa = 0.3;
            p.ib.ax.g_Leak = 0.25;
            p.ib.ax.g_gja = 0.002;
            p.ib.ax.C = 1;
            
            p.ib.ax.J = 3;
            p.setIbAxJ(p.ib.ax.J);
            
            % so
            
            p.ib.so.n_current_param = 2; % n of updated parameters in diffeq
            
            p.ib.so.g_NaFs = 50;
            p.ib.so.g_KDRs = 10;
            p.ib.so.g_as = 0.3;
            p.ib.so.g_Leak = 1;
            p.ib.so.g_ds = 0.5;
            p.ib.so.C = 1;
            
            p.ib.so.J = -1.5;
            p.setIbSoJ(p.ib.so.J);
            
            % set connectivity
            p.connect_mode = 'all';
            p.setConnectivity(p.connect_mode)
            
        end
        
        % Initial Voltage Setters
        
        function setIbAdInitV(self,Vinit)
            self.ib.ad.Vinit = Vinit;
            for i_ib = 1:self.ib.n
                self.ib.ad.cell{i_ib}.V_init = self.ib.V_init;
            end
        end
        
        function setIbAxInitV(self,Vinit)
            self.ib.ax.Vinit = Vinit;
            for i_ib = 1:self.ib.n
                self.ib.ax.cell{i_ib}.V_init = self.ib.V_init;
            end
        end
        
        function setIbSoInitV(self,Vinit)
            self.ib.so.Vinit = Vinit;
            for i_ib = 1:self.ib.n
                self.ib.so.cell{i_ib}.V_init = self.ib.V_init;
            end
        end
        
        function setLtsInitV(self,Vinit)
            self.lts.Vinit = Vinit;
            for i_ib = 1:self.lts.n
                self.lts.cell{i_ib}.V_init = self.lts.V_init;
            end
        end
        
        % Input Voltage Setters
        
        function setIbSoJ(self,J)
            self.ib.so.J = J;
            for i_ib = 1:self.ib.n
                self.ib.so.cell{i_ib}.J = self.ib.so.J;
            end
        end
        
        function setIbAxJ(self,J)
            self.ib.ax.J = J;
            for i_ib = 1:self.ib.n
                self.ib.ax.cell{i_ib}.J = self.ib.ax.J;
            end
        end
        
        function setIbAdJ(self,J)
            self.ib.ad.J = J;
            for i_ib = 1:self.ib.n
                self.ib.ad.cell{i_ib}.J = self.ib.ad.J;
            end
        end
        
        function setLtsJ(self,J)
            self.lts.J = J;
            for i_ib = 1:self.lts.n
                self.lts.cell{i_ib}.J = self.lts.J;
            end
        end
        
        % Connectivity setters
        
        function setG_LD(self,g_Ld)
            self.ib.ad.g_Ld = g_Ld;
            self.updateConnectivity();
        end
        
        function setG_Id(self,g_Id)
            self.ib.ad.g_Id = g_Id;
            self.updateConnectivity();
        end
        
        function setG_LL(self,g_LL)
            self.lts.g_LL = g_LL;
            self.updateConnectivity();
        end
        
        function setG_aL(self,g_aL)
            self.lts.g_aL = g_aL;
            self.updateConnectivity();
        end
        
        function setConnectivity(self,conn_mode)
            self.connect.ib.lts = 1;
            self.connect.ib.ib = 1;
            self.connect.lts.lts = 1;
            self.connect.lts.ib = 1;
            
            switch lower(conn_mode)
                case {'disconnected'}
                    self.connect.ib.lts = 0;
                    self.connect.ib.ib = 0;
                    self.connect.lts.lts = 0;
                    self.connect.lts.ib = 0;
                case {'detached'}
                    self.connect.ib.lts = 0;
                    self.connect.lts.ib = 0;
                case {'ib->lts'}
                    self.connect.lts.ib = 0;
                case {'lts->ib'}
                    self.connect.ib.lts = 0;
                case {'all'}
                otherwise
            end
            
            self.updateConnectivity();
        end
        
        function updateConnectivity(self)
            
            % connections to IB cells
            for i_ib = 1:self.ib.n
                
                % synaptic strength parameters
                self.ib.ad.cell{i_ib}.lts_gate = zeros(1,self.lts.n);
                if self.connect.ib.lts
                    for is_lts = 1:self.lts.n
                        self.ib.ad.cell{i_ib}.lts_gate(is_lts) = self.ib.ad.g_Ld;
                    end
                end
                
                self.ib.ad.cell{i_ib}.ib_gate = zeros(1,self.ib.n);
                if self.connect.ib.ib
                    for is_ib = 1:self.ib.n
                        self.ib.ad.cell{i_ib}.ib_gate(is_ib) = self.ib.ad.g_dI;
                    end
                end
            end
            
            % connections to LTS cells
            for i_lts = 1:self.lts.n
                self.lts.cell{i_lts}.lts_gate = zeros(1,self.lts.n);
                if self.connect.lts.lts
                    for is_lts = 1:self.lts.n
                        self.lts.cell{i_lts}.lts_gate(is_lts) = self.lts.g_LL;
                    end
                end
                
                self.lts.cell{i_lts}.ib_gate = zeros(1,self.ib.n);
                if self.connect.ib.lts
                    for is_ib = 1:self.ib.n
                        self.lts.cell{i_lts}.ib_gate(is_ib) = self.lts.g_aL;
                    end
                end
            end
        end
        
        function setNCells(self,n_lts,n_ib)
            % setNCells - set number of LTS and IB cells in the model
            
            self.lts.n = n_lts;
            self.ib.n = n_ib;
            self.n_cells = self.lts.n + self.ib.n;
        end
        
        function setTimeBySteps(self,dt,n_steps)
            % setTimeByMaxTime - set the amount of time the simulation runs for using the time
            % step and the number of steps
            self.dt = dt;
            self.n_steps = n_steps;
            self.max_time = dt*n_steps;
            self.time = 0:self.dt:self.max_time;
        end
        
        function setTimeByMaxTime(self,dt,max_time)
            % setTimeByMaxTime - set the amount of time the simulation runs for using the time
            % step and the last time point (max time)
            self.dt = dt;
            self.n_steps = ceil(max_time/dt);
            self.max_time = self.dt*self.n_steps;
            self.time = 0:self.dt:self.max_time;
        end
        
        function setNSteps(self,n_steps)
           self.setTimeBySteps(self.dt,n_steps);
        end
        
        function setMaxTime(self,max_time)
           self.setTimeByMaxTime(self.dt,max_time);
        end
    end
end